#!/usr/bin/env python3
"""
SkyWalking 数据采集服务
主入口：加载配置、初始化数据库、启动调度器
"""

import os
import sys
import signal
import logging
from pathlib import Path
from dotenv import load_dotenv

# 添加当前目录到 Python 路径
sys.path.insert(0, str(Path(__file__).parent))

# 创建必要的目录
BASE_DIR = Path(__file__).parent
LOGS_DIR = BASE_DIR / 'logs'
DATA_DIR = BASE_DIR / 'data'

LOGS_DIR.mkdir(exist_ok=True)
DATA_DIR.mkdir(exist_ok=True)

from database.db_manager import DatabaseManager
from collector.scheduler import CollectionScheduler


# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler(LOGS_DIR / 'collector_service.log')
    ]
)

logger = logging.getLogger(__name__)


class CollectorService:
    """采集服务主类"""
    
    def __init__(self):
        self.scheduler = None
        self.db_manager = None
    
    def _check_first_run(self):
        """检查是否是首次运行（数据库中是否有数据）"""
        try:
            latest_log = self.db_manager.get_latest_collection_log()
            return latest_log is None
        except Exception:
            return True
    
    def load_config(self):
        """加载配置文件"""
        # 加载 .env 文件
        env_path = Path(__file__).parent / "config.env"
        if env_path.exists():
            load_dotenv(env_path)
            logger.info(f"Loaded configuration from {env_path}")
        else:
            logger.warning(f"Configuration file not found: {env_path}")
        
        # 读取配置
        config = {
            'skywalking_url': os.getenv('SKYWALKING_URL', 'http://10.10.50.46:12800/graphql'),
            'database_url': os.getenv('DATABASE_URL', 'sqlite:///data/skywalking_data.db'),
            'service_names': os.getenv('DEFAULT_SERVICE_NAME', 'springboot-apm-demo').split(','),
            'collection_interval': int(os.getenv('COLLECTION_INTERVAL', '30')),
            'time_range': int(os.getenv('DEFAULT_TIME_RANGE', '30')),
            'data_retention_days': int(os.getenv('DATA_RETENTION_DAYS', '90')),
            'initial_backfill_range': int(os.getenv('INITIAL_BACKFILL_RANGE', '0'))
        }
        
        # 清理服务名称列表（去除空格）
        config['service_names'] = [name.strip() for name in config['service_names'] if name.strip()]
        
        logger.info("Configuration:")
        logger.info(f"  SkyWalking URL: {config['skywalking_url']}")
        logger.info(f"  Database URL: {config['database_url']}")
        logger.info(f"  Service Names: {config['service_names']}")
        logger.info(f"  Collection Interval: {config['collection_interval']} minutes")
        logger.info(f"  Time Range: {config['time_range']} minutes")
        logger.info(f"  Data Retention: {config['data_retention_days']} days")
        logger.info(f"  Initial Backfill Range: {config['initial_backfill_range']} minutes")
        
        return config
    
    def start(self):
        """启动服务"""
        logger.info("=" * 80)
        logger.info("SkyWalking Data Collection Service")
        logger.info("=" * 80)
        
        try:
            # 1. 加载配置
            config = self.load_config()
            
            # 2. 初始化数据库
            logger.info("Initializing database...")
            self.db_manager = DatabaseManager(
                database_url=config['database_url'],
                echo=False  # 生产环境不输出 SQL 日志
            )
            logger.info("Database initialized successfully")
            
            # 3. 检查是否是首次启动（数据库是否为空）
            is_first_run = self._check_first_run()
            if is_first_run and config['initial_backfill_range'] > 0:
                logger.info(f"🔄 First run detected! Will backfill {config['initial_backfill_range']} minutes of historical data")
                initial_time_range = config['initial_backfill_range']
            else:
                initial_time_range = config['time_range']
            
            # 4. 创建调度器
            logger.info("Creating scheduler...")
            self.scheduler = CollectionScheduler(
                skywalking_url=config['skywalking_url'],
                database_manager=self.db_manager,
                service_names=config['service_names'],
                collection_interval_minutes=config['collection_interval'],
                time_range_minutes=config['time_range'],
                initial_time_range_minutes=initial_time_range
            )
            
            # 4. 启动调度器（阻塞）
            logger.info("Starting collection scheduler...")
            self.scheduler.start()
        
        except KeyboardInterrupt:
            logger.info("Received keyboard interrupt")
            self.stop()
        except Exception as e:
            logger.error(f"Service failed to start: {str(e)}", exc_info=True)
            sys.exit(1)
    
    def stop(self):
        """停止服务"""
        logger.info("Stopping service...")
        
        if self.scheduler:
            try:
                self.scheduler.stop()
            except Exception as e:
                logger.error(f"Error stopping scheduler: {str(e)}")
        
        if self.db_manager:
            try:
                self.db_manager.close()
                logger.info("Database connection closed")
            except Exception as e:
                logger.error(f"Error closing database: {str(e)}")
        
        logger.info("Service stopped")
    
    def signal_handler(self, signum, frame):
        """信号处理器"""
        logger.info(f"Received signal {signum}")
        self.stop()
        sys.exit(0)


def main():
    """主函数"""
    service = CollectorService()
    
    # 注册信号处理器
    signal.signal(signal.SIGINT, service.signal_handler)
    signal.signal(signal.SIGTERM, service.signal_handler)
    
    # 启动服务
    service.start()


if __name__ == '__main__':
    main()

